package com.abing.permissionsys.utils;

import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
public class RedisUtil {

	private String prefix = "PermissionSys:";

	@Resource
	private RedisTemplate<String,Object> redisTemplate;

	/**
	 * 如果key存在的话返回fasle 不存在的话返回true
	  */
	public Boolean setNx(String key, String value, Long timeout) {
		Boolean setIfAbsent = redisTemplate.opsForValue().setIfAbsent(prefix+key, value);
		if (timeout != null) {
			redisTemplate.expire(prefix+key, timeout, TimeUnit.SECONDS);
		}
		return setIfAbsent;
	}

	public RedisTemplate getStringRedisTemplate() {
		return redisTemplate;
	}

	public void setList(String key, List<String> listToken) {
		redisTemplate.opsForList().leftPushAll(key, listToken);
	}
	/**
	 * 存放string类型
	 *
	 * @param key
	 *            key
	 * @param data
	 *            数据
	 * @param timeout
	 *            超时间
	 */
	public void setObject(String key, Object data, Long timeout) {
		try {

			redisTemplate.opsForValue().set(prefix+key, data);
			if (timeout != null) {
				//分钟为单位
				redisTemplate.expire(prefix+key, timeout, TimeUnit.MINUTES);
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * 开启Redis 事务
	 *
	 */
	public void begin() {
		// 开启Redis 事务权限
		redisTemplate.setEnableTransactionSupport(true);
		// 开启事务
		redisTemplate.multi();

	}

	/**
	 * 提交事务
	 *
	 */
	public void exec() {
		// 成功提交事务
		redisTemplate.exec();
	}

	/**
	 * 回滚Redis 事务
	 */
	public void discard() {
		redisTemplate.discard();
	}

	/**
	 * 存放string类型
	 *
	 * @param key
	 *            key
	 * @param data
	 *            数据
	 */
	public void setObject(String key, Object data) {
		setObject(key, data, null);
	}

	/**
	 * 根据key查询string类型
	 *
	 * @param key
	 * @return
	 */
	public Object getObject(String key) {
		Object value = redisTemplate.opsForValue().get(prefix+key);
		return value;
	}

	/**
	 * 根据对应的key删除key
	 *
	 * @param key
	 */
	public Boolean delKey(String key) {
		return redisTemplate.delete(prefix+key);

	}
	/**
	 * 根据对应的key删除key
	 *
	 * @param keys
	 */
	public void delKey(Set<String> keys) {
		 redisTemplate.delete(prefix+keys);
	}
	/**
	 * 获取redis的key
	 *
	 * @param key
	 */
	public Set<String> keys(String key) {
		return redisTemplate.keys(prefix+key);

	}
	/**
	 * 获取redis的size
	 *
	 */
	public Long dbSize() {
		Long size = redisTemplate.execute(new RedisCallback<Long>() {
			@Override
			public Long doInRedis(RedisConnection connection) throws DataAccessException {
				return connection.dbSize();
			}
		});
		return size;
	}
	/**
	 * @Title: generate
	 * @Description: Atomically increments by one the current value.
	 * @param key
	 * @return
	 */
	public long generate(String key) {
		RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
		return counter.incrementAndGet();
	}

	/**
	 * @Title: generate
	 * @Description: Atomically increments by one the current value.
	 * @param key
	 * @return
	 */
	public long generate(String key, Date expireTime) {
		RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
		counter.expireAt(expireTime);
		return counter.incrementAndGet();
	}

	/**
	 * @Title: generate
	 * @Description: Atomically adds the given value to the current value.
	 * @param key
	 * @param increment
	 * @return
	 */
	public long generate(String key,int increment) {
		RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
		return counter.addAndGet(increment);
	}

	/**
	 * @Title: generate
	 * @Description: Atomically adds the given value to the current value.
	 * @param key
	 * @param increment
	 * @param expireTime
	 * @return
	 */
	public long generate(String key,int increment,Date expireTime) {
		RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
		counter.expireAt(expireTime);
		return counter.addAndGet(increment);
	}

}
